package roboSoccer;

/**
 * An abstract class that provides a framework for classes that allow
 * communication and control with the physical robots. With this class as a
 * base, different control classes that implement this class can be switched out
 * for one another for use in controlling multiple kinds of robots, without
 * having to change any behavior code.
 * <p>
 * This class is in development and methods are subject to change as the
 * required functionality for driving any robot is not entirely clear.
 * 
 * @author Ben Hopkins
 * 
 */
public abstract class Control {

	/**
	 * Used to track whether or not the object can successfully communicate with
	 * the robot. If it can't, an error may occur without checking this.
	 */
	public boolean functioning;

	/**
	 * Move forward.
	 * 
	 * @param speed
	 *            The speed at which to move forward.
	 */
	public abstract void forward(int speed);

	/**
	 * Rotate command.
	 * 
	 * @param speed
	 *            The speed at which to rotate, where negative should rotate
	 *            left (c-clockwise) and positive should rotate right
	 *            (clockwise).
	 */
	public abstract void rotate(int speed);
	
	/**
	 * Stop all motor movement command.
	 */
	public abstract void stop();
	
	/**
	 * Dribbler is spinning while this command is sent.
	 */
	public abstract void dribble();
	
	/**
	 * Tells robot to kick.
	 * @param power From 1-100, the amount of power applied to the kick.
	 */
	public abstract void kick(int power);
	
	/**
	 * Commands a robot to go to a location on the field.
	 * 
	 * @param game Current physical state of the game.
	 * @param r The robot which will take the command.
	 * @param location Vector for the location of the object on the field.
	 * @param turnSpeed Speed with which to turn.
	 * @param driveSpeed Speed with which to drive.
	 * @param leniency How close the robot's angle should be to the ideal calculated angle before moving forwards.
	 * @param targetR The radius of the object the robot is driving towards.
	 * @return Returns true if the robot reaches the radius given in the position of the object.
	 */
	public abstract boolean goToLocation(GameState game, RoboPlayer r,
			Vector location, int turnSpeed, int driveSpeed, int leniency,
			int targetR);
	
	/**
	 * Commands a robot to turn towards a location on the field.
	 * 
	 * @param game Current physical state of the game.
	 * @param r The robot which will take the command.
	 * @param location Vector for the location of the object to turn to.
	 * @param turnSpeed Speed with which to turn.
	 * @param leniency How close the robot's angle should be to the ideal calculated angle.
	 * @return Returns true if the robot turns in the direction of the location.
	 */
	public abstract boolean turnTowardsLocation(GameState game, RoboPlayer r,
			Vector location, int turnSpeed, int leniency);

	/**
	 * Commands a robot to turn to an angle
	 * 
	 * @param game Current physical state of the game.
	 * @param r The robot which will take the command.
	 * @param direction A vector whose direction is the direction to turn to. 
	 * 					NOT THE DIRECTION OF THE VECTOR.
	 * @param turnSpeed Speed with which to turn.
	 * @param leniency How close the robot's angle should be to the ideal calculated angle.
	 * @return Returns if the direction has been turned to within leniency.
	 */
	public abstract boolean turnToDirection(GameState game, RoboPlayer r,
			Vector direction, int turnSpeed, int leniency);
}
